package com.gpio;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.dao.EquipmentInfoStateMapper;
import com.model.EquipmentInfoState;

/**
 * @author lotey
 * @date 2017年2月27日 下午5:21:58
 * @desc GPIO服务器程序入口
 */
public class GPIOServer {
	
	private static Logger logger = LogManager.getLogger(GPIOServer.class);
	
	//正常设备状态
	public static final String DEIVCE_STATE_NORMAL_1 = "1";
	public static final String DEIVCE_STATE_NORMAL_2 = "2";
	//故障设备状态
	public static final String DEIVCE_STATE_FAULT_3 = "3";
	public static final String DEIVCE_STATE_FAULT_4 = "4";
	
	//定义存放故障信息的列表
	private static List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
	
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
		logger.info("=============={}spring容器已启动==============",DateTimeUtil.getCurrentDateTimeStr());
		EquipmentInfoStateMapper equipmentInfoStateMapper = (EquipmentInfoStateMapper) context.getBean("equipmentInfoStateMapper");
		List<EquipmentInfoState> equList = null;
		//初始化GPIO控制线程
		GPIOControlThread thread = new GPIOControlThread(list);
		
		//固定测试，写入固定设备编号
//		equList = new ArrayList<EquipmentInfoState>();
//		EquipmentInfoState equipmentInfo = new EquipmentInfoState();
//		equipmentInfo.setDeviceId("371502000000011000");
//		equipmentInfo.setDeviceState("4");
//		equList.add(equipmentInfo);
		
		//主线程5分钟刷新一次所有设备的状态信息，并将设备状态信息传给阻塞队列，进而交给子线程处理
		int faultType = 0;//故障类型
		int lightNum = 0;//设备编号
		Map<String, Object> map = null;//队列存储的map
		//将未映射的文件写入/home/pi/un-mapping.txt文件
		BufferedWriter unMappingWriter = null;
		BufferedWriter dbBreakdownWriter = null;
		//设备状态
		String deviceStatus = null;
		while (true) {
			logger.info("======================={}故障设备轮训检测开始=======================",DateTimeUtil.getCurrentDateTimeStr());
			try {
				unMappingWriter = new BufferedWriter(new FileWriter(new File("/home/pi/mqserver/un-mapping.txt"),false));
				dbBreakdownWriter = new BufferedWriter(new FileWriter(new File("/home/pi/mqserver/db-breakdown-equ.txt"),false));
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			equList = equipmentInfoStateMapper.selectAllEqumentInfo();
			if (equList != null && equList.size() > 0) {
				int index = 0;
				for (EquipmentInfoState equipmentInfoState : equList) {
					index++;
					deviceStatus = equipmentInfoState.getDeviceState();
					try {
						if(DEIVCE_STATE_NORMAL_1.equals(deviceStatus) || DEIVCE_STATE_NORMAL_2.equals(deviceStatus)) {//正常状态
							faultType = 4;
						}
						if(DEIVCE_STATE_FAULT_3.equals(deviceStatus) || DEIVCE_STATE_FAULT_4.equals(deviceStatus)) {//正常状态
							faultType = 1;
							//将读取数据库时，故障设备写入文件
							dbBreakdownWriter.write(equipmentInfoState.getDeviceId() + "\n");
							dbBreakdownWriter.flush();
//							logger.info("======================={}故障设备状态存放成功,已放入{}个设备状态信息=======================",DateTimeUtil.getCurrentDateTimeStr(),index);
						}
//						logger.info("======================={}当前设备编号为：{} deviceState：{} faultType {}=======================",DateTimeUtil.getCurrentDateTimeStr(),equipmentInfoState.getDeviceId(),equipmentInfoState.getDeviceState(),faultType);
						if (EquipmentConstant.equipmentMap.get(equipmentInfoState.getDeviceId()) == null) {
//							logger.error(">>>>>>>>>>>>>>>>>>>>>>设备映射文件中不存在设备标号为：{}的设备，请检查核   实 >>>>>>>>>>>>>>>>>>>>>>",equipmentInfoState.getDeviceId());
							index--;
							//将未映射的设备编号写入文件
							unMappingWriter.write(equipmentInfoState.getDeviceId() + "\n");
							unMappingWriter.flush();
							continue;
						}
						lightNum = EquipmentConstant.equipmentMap.get(equipmentInfoState.getDeviceId());
						map = new HashMap<String, Object>(4);
						map.put("lightNum", lightNum);
						map.put("faultType", faultType);
						map.put("isIgnore", 1);
						map.put("deviceID", equipmentInfoState.getDeviceId());
						list.add(map);
//						logger.info("======================={}设备状态放入队列成功,已放入{}个设备信息=======================",DateTimeUtil.getCurrentDateTimeStr(),index);
					} catch (Exception e) {
						logger.error("======================={}设备状态放入队列出现异常，设备编号：{} 详细信息：{}=======================",DateTimeUtil.getCurrentDateTimeStr(),equipmentInfoState.getDeviceId(),e);
						e.printStackTrace();
					}
				}
			}
			//关闭文件输出流
			try {
				unMappingWriter.close();
				dbBreakdownWriter.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			//执行控制线程
			thread.run(list);
			try {
				logger.info("======================={}主线程进入休眠中，5分钟后继续拉取设备信息=======================",DateTimeUtil.getCurrentDateTimeStr());
				Thread.sleep(5*60*1000);//线程休眠5分钟
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}